package com.uairobot.tts.client.biaobei;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.util.HashMap;
import java.util.Map;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bill.utils.http.JdkHttpClient;
import com.uairobot.bill.tts.agent.utils.PropKitUtil;

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class BiaoBeiClient {
  private String baseUrl = PropKitUtil.get("addr.bill-biaobei-tts-agent");
  private String accessTokenUrl = baseUrl + "/oauth/2.0/token";
  private String checkTokenUrl = baseUrl + "/api/checkToken";
  private String ttsUrl = baseUrl + "/tts";
  private String clientId = "1cae6918-0bc7-4220-934c-57e83a15d58e";
  private String clientSecret = "NjU1N2ZhYTAtNjUzNi00OTI4LWIwNmYtYzE1N2JjMTZjOTA3";

  private String accessToken;
  // 过期时间,单位s
  private Long expireTime = 0L;

  public String getAccessToken() {
    if (System.currentTimeMillis() / 1000 > expireTime) {
      String string = getAccessToken(clientId, clientSecret);
      JSONObject parseObject = JSON.parseObject(string);
      accessToken = parseObject.getString("access_token");
      Integer integer = parseObject.getInteger("expires_in");
      expireTime = System.currentTimeMillis() / 1000 + integer;
    }
    return accessToken;

  }

  public String getAccessToken(String clientId, String clientSecret) {
    HashMap<String, String> params = new HashMap<>();
    params.put("grant_type", "client_credentials");
    params.put("client_id", clientId);
    params.put("client_secret", clientSecret);
    StringBuffer strBuf = JdkHttpClient.get(accessTokenUrl, null, params);
    return strBuf.toString();
  }

  public String checkToken(String accessToken) {
    Map<String, String> hdeader = new HashMap<>();
    hdeader.put("content-type", "application/json");
    Map<String, String> params = new HashMap<>();
    params.put("access_token", accessToken);
    StringBuffer strBuf = JdkHttpClient.get(checkTokenUrl, hdeader, params);
    return strBuf.toString();
  }

  /**
   * Map合成成功map中的code是1,合成失败,map中的code是-1 
   * @param m 
   * @param l 
   * @param k 
   * @param j 
   * @param i 
   */
  public Map<String, Object> tts(String language, String voiceName, String text, Integer speed, Integer volume, Integer pitch,
      Integer audioType, Integer rate) {
    String accessToken = getAccessToken();
    Map<String, String> params = new HashMap<>();
    params.put("access_token", accessToken);
    params.put("domain", "1");
    params.put("language", language);
    params.put("voice_name", voiceName);
    params.put("text", text);
    params.put("speed", speed + "");
    params.put("volume", volume + "");
    params.put("pitch", pitch + "");
    params.put("audiotype", audioType + "");
    params.put("rate", rate + "");

    log.info("send:" + params.toString());
    HttpURLConnection httpConn = JdkHttpClient.postStream(ttsUrl, null, params);

    int responseCode = 0;
    try {
      responseCode = httpConn.getResponseCode();
    } catch (IOException e) {
      e.printStackTrace();
    }
    Map<String, Object> map = new HashMap<>();
    ByteArrayOutputStream baos = null;
    if (responseCode == 200) {
      baos = JdkHttpClient.getOutputStram(httpConn);
      httpConn.disconnect();
      String contentType = httpConn.getHeaderField("Content-Type");

      while (contentType.contains("application/json")) {
        String string = new String(baos.toByteArray());
        System.out.println("BiaoBeiClient.tts():请求失败,返回json格式:" + string);
        // 判断失败的原因如果是30001,再次请求,如果不是返回json
        JSONObject jsonObject = JSON.parseObject(string);
        if (jsonObject.getInteger("err_no") != 30001) {
          map.put("code", "-1");
          map.put("msg", string);
          return map;
        }
        // 休眠3s,3s后再次请求
        try {
          Thread.sleep(3000);
        } catch (InterruptedException e1) {
          e1.printStackTrace();
        }
        System.out.println("BiaoBeiClient.tts():再次合成");
        httpConn = JdkHttpClient.postStream(ttsUrl, null, params);
        try {
          responseCode = httpConn.getResponseCode();
        } catch (IOException e) {
          e.printStackTrace();
        }
        if (responseCode == 200) {
          baos = JdkHttpClient.getOutputStram(httpConn);
          contentType = httpConn.getHeaderField("Content-Type");
          httpConn.disconnect();
        } else {
          throw new RuntimeException("HTTP POST Request Failed with Error " + JdkHttpClient.getFailMessage(httpConn));
        }
      }
    } else {
      throw new RuntimeException("HTTP POST Request Failed with Error " + JdkHttpClient.getFailMessage(httpConn));
    }
    map.put("code", "1");
    map.put("data", baos);
    return map;
  }
}